/*
 * $Id: wstring.h,v 1.34 2007-03-22 11:30:11 bacon Exp $
 */

#ifndef _XP_BAS_WSTRING_H_
#define _XP_BAS_WSTRING_H_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/stdarg.h>

#define XP_WSTRFNMAT_PATHNAME (1 << 0)
#define XP_WSTRFNMAT_NOESCAPE (1 << 1)
#define XP_WSTRFNMAT_PERIOD   (1 << 2)
#define XP_WSTRFNMAT_CASEFOLD (1 << 3)

typedef struct xp_wvstr_t xp_wvstr_t;

struct xp_wvstr_t
{
	xp_wchar_t   buffer_space[256];
	xp_wchar_t*  buffer;
	xp_size_t    buffer_capacity;
	xp_size_t    buffer_ubound;

	xp_wchar_t*  vector_space[64 + 1];
	xp_wchar_t** vector;
	xp_size_t    vector_capacity;
	xp_size_t    vector_ubound;

	xp_bool_t __dynamic;
};

#ifdef __cplusplus
extern "C" {
#endif

xp_size_t xp_wstrlen (const xp_wchar_t* str);
xp_size_t xp_wstrsize (const xp_wchar_t* str);  /* xp_wstrlen + 1 */
xp_size_t xp_wstrlenn (const xp_wchar_t* str, xp_size_t max);
xp_size_t xp_wstrsizen (const xp_wchar_t* str, xp_size_t max);

xp_size_t xp_wstrset (xp_wchar_t* buf, xp_wchar_t c, xp_size_t n);
xp_size_t xp_wstrxset (xp_wchar_t* buf, xp_size_t bsz, xp_wchar_t c, xp_size_t n);

xp_size_t xp_wstrcpy (xp_wchar_t* buf, const xp_wchar_t* str);
xp_size_t xp_wstrcpyn (xp_wchar_t* buf, const xp_wchar_t* str, xp_size_t n);
xp_size_t xp_wstrncpy (xp_wchar_t* buf, const xp_wchar_t* str, xp_size_t len);
xp_size_t xp_wstrxcpy (xp_wchar_t* buf, xp_size_t bsz, const xp_wchar_t* str);
xp_size_t xp_wstrxncpy (
	xp_wchar_t* buf, xp_size_t bsz, const xp_wchar_t* str, xp_size_t len);

xp_size_t xp_wstrcat (xp_wchar_t* buf, const xp_wchar_t* str);
xp_size_t xp_wstrcatn (xp_wchar_t* buf, const xp_wchar_t* str, xp_size_t n);
xp_size_t xp_wstrncat (xp_wchar_t* buf, const xp_wchar_t* str, xp_size_t len);
xp_size_t xp_wstrxcat (xp_wchar_t* buf, xp_size_t bsz, const xp_wchar_t* str);
xp_size_t xp_wstrxncat (
	xp_wchar_t* buf, xp_size_t bsz, const xp_wchar_t* str, xp_size_t len);
xp_size_t xp_wstrxapp (xp_wchar_t* buf, xp_size_t size, ...);
xp_size_t xp_wstrxappv (xp_wchar_t* buf, xp_size_t size, xp_va_list ap);
xp_size_t xp_wstrxcap (xp_wchar_t* buf, xp_size_t size, ...);
xp_size_t xp_wstrxcapv (xp_wchar_t* buf, xp_size_t size, xp_va_list ap);

int xp_wstrcmp (const xp_wchar_t* s1, const xp_wchar_t* s2);
int xp_wstrcmpn (const xp_wchar_t* s1, const xp_wchar_t* s2, xp_size_t count);
int xp_wstrxcmp (const xp_wchar_t* s1, xp_size_t len, const xp_wchar_t* s2);
int xp_wstrxncmp (
	const xp_wchar_t* s1, xp_size_t len1,
	const xp_wchar_t* s2, xp_size_t len2);

int xp_wstrcasecmp (const xp_wchar_t* s1, const xp_wchar_t* s2);
int xp_wstrcasecmpn (const xp_wchar_t* s1, const xp_wchar_t* s2, xp_size_t n);
int xp_wstrxcasecmp (const xp_wchar_t* s1, xp_size_t len, const xp_wchar_t* s2);
int xp_wstrxncasecmp (
	const xp_wchar_t* s1, xp_size_t len1, 
	const xp_wchar_t* s2, xp_size_t len2);

xp_wchar_t* xp_wstrstr (const xp_wchar_t* str, const xp_wchar_t* sub);
xp_wchar_t* xp_wstrxstr (
	const xp_wchar_t* str, xp_size_t size, const xp_wchar_t* sub);
xp_wchar_t* xp_wstrxnstr (const xp_wchar_t* str,
	xp_size_t strsz, const xp_wchar_t* sub, xp_size_t subsz);

xp_wchar_t* xp_wstrrstr (const xp_wchar_t* str, const xp_wchar_t* sub);
xp_wchar_t* xp_wstrxrstr (
	const xp_wchar_t* str, xp_size_t size, const xp_wchar_t* sub);
xp_wchar_t* xp_wstrxnrstr (const xp_wchar_t* str,
	xp_size_t strsz, const xp_wchar_t* sub, xp_size_t subsz);

xp_wchar_t* xp_wstrchr (const xp_wchar_t* str, xp_wcint_t c);
xp_wchar_t* xp_wstrxchr (const xp_wchar_t* str, xp_size_t len, xp_wcint_t c);
xp_wchar_t* xp_wstrrchr (const xp_wchar_t* str, xp_wcint_t c);
xp_wchar_t* xp_wstrxrchr (const xp_wchar_t* str, xp_size_t len, xp_wcint_t c);

xp_wchar_t* xp_wstrpbrk (const xp_wchar_t* str, const xp_wchar_t* needle);
xp_wchar_t* xp_wstrxpbrk (
	const xp_wchar_t* str, xp_size_t n, const xp_wchar_t* needle);
xp_wchar_t* xp_wstrnpbrk (
	const xp_wchar_t* str, const xp_wchar_t* needle, xp_size_t n);
xp_wchar_t* xp_wstrxnpbrk (
	const xp_wchar_t* str, xp_size_t n1, const xp_wchar_t* needle, xp_size_t n2);

xp_wchar_t* xp_wstrrpbrk (const xp_wchar_t* str, const xp_wchar_t* needle);
xp_wchar_t* xp_wstrxrpbrk (
	const xp_wchar_t* str, xp_size_t n, const xp_wchar_t* needle);
xp_wchar_t* xp_wstrnrpbrk (
	const xp_wchar_t* str, const xp_wchar_t* needle, xp_size_t n);
xp_wchar_t* xp_wstrxnrpbrk (
	const xp_wchar_t* str, xp_size_t n1, const xp_wchar_t* needle, xp_size_t n2);

xp_size_t xp_wstrspn (
	const xp_wchar_t* str1, const xp_wchar_t* str2);
xp_size_t xp_wstrxspn (
	const xp_wchar_t* str1, xp_size_t n1, const xp_wchar_t* str2);
xp_size_t xp_wstrnspn (
	const xp_wchar_t* str1, const xp_wchar_t* str2, xp_size_t n2);
xp_size_t xp_wstrxnspn (
	const xp_wchar_t* str1, xp_size_t n1, const xp_wchar_t* str2, xp_size_t n2);

xp_size_t xp_wstrcspn (
	const xp_wchar_t* str1, const xp_wchar_t* str2);
xp_size_t xp_wstrxcspn (
	const xp_wchar_t* str1, xp_size_t n1, const xp_wchar_t* str2);
xp_size_t xp_wstrncspn (
	const xp_wchar_t* str1, const xp_wchar_t* str2, xp_size_t n2);
xp_size_t xp_wstrxncspn (
	const xp_wchar_t* str1, xp_size_t n1, const xp_wchar_t* str2, xp_size_t n2);

xp_size_t xp_wstrrot (xp_wchar_t* str, int dir, xp_size_t n);
xp_size_t xp_wstrxrot (xp_wchar_t* str, xp_size_t len, int dir, xp_size_t n);
xp_size_t xp_wstrrev (xp_wchar_t* str);
xp_size_t xp_wstrxrev (xp_wchar_t* str, xp_size_t len);

xp_wchar_t* xp_wstrdup (const xp_wchar_t* str);
xp_wchar_t* xp_wstrxdup (const xp_wchar_t* str, xp_size_t len);
xp_wchar_t* xp_wstrxdup2 (
	const xp_wchar_t* str1, xp_size_t len1,
	const xp_wchar_t* str2, xp_size_t len2);

xp_size_t xp_wstrdel (xp_wchar_t* str, xp_size_t pos, xp_size_t n);
xp_size_t xp_wstrxdel (xp_wchar_t* str, xp_size_t len, xp_size_t pos, xp_size_t n);
xp_size_t xp_wstrrmchr (xp_wchar_t* str, xp_wcint_t c);
xp_size_t xp_wstrxrmchr (xp_wchar_t* str, xp_size_t len, xp_wcint_t c);

xp_bool_t xp_wstristype (
	const xp_wchar_t* str, xp_bool_t(*ctype_func)(xp_wcint_t c));
xp_bool_t xp_wstrxistype (
	const xp_wchar_t* str, xp_size_t len, xp_bool_t(*ctype_func)(xp_wcint_t c));

xp_size_t xp_wstrupr (xp_wchar_t* str);
xp_size_t xp_wstrxupr (xp_wchar_t* str, xp_size_t len);
xp_size_t xp_wstrlwr (xp_wchar_t* str);
xp_size_t xp_wstrxlwr (xp_wchar_t* str, xp_size_t len);

xp_size_t xp_wstrtrm (xp_wchar_t* str);
xp_size_t xp_wstrxtrm (xp_wchar_t* str, xp_size_t len);
xp_size_t xp_wstrpac (xp_wchar_t* str);
xp_size_t xp_wstrxpac (xp_wchar_t* str, xp_size_t len);

xp_wchar_t* xp_wstrtok  (
	const xp_wchar_t*, const xp_wchar_t*, xp_wchar_t**, xp_size_t*);
xp_wchar_t* xp_wstrxtok (const xp_wchar_t* s, xp_size_t len,
	const xp_wchar_t* delim, xp_wchar_t** tok, xp_size_t* tok_len);
xp_wchar_t* xp_wstrxntok (
	const xp_wchar_t* s, xp_size_t len,
	const xp_wchar_t* delim, xp_size_t delim_len,
	xp_wchar_t** tok, xp_size_t* tok_len);

int xp_wstrspl (xp_wchar_t* s, const xp_wchar_t* delim, 
	xp_wchar_t lquote, xp_wchar_t rquote, xp_wchar_t escape, xp_size_t* count);
int xp_wstrspls (
	xp_wchar_t* s, const xp_wchar_t* delim, xp_wchar_t lquote, xp_wchar_t rquote, 
	xp_wchar_t escape, xp_size_t* count, xp_wchar_t* ptrs[]);

int xp_wstrfnmat (const xp_wchar_t* str, const xp_wchar_t* ptn, int flags);
xp_bool_t xp_wstrxfnmat  (
	const xp_wchar_t* str, xp_size_t slen, const xp_wchar_t* ptn, int flags);
xp_bool_t xp_wstrnfnmat  (
	const xp_wchar_t* str, const xp_wchar_t* ptn, xp_size_t plen, int flags);
int xp_wstrxnfnmat (
	const xp_wchar_t* str, xp_size_t slen, 
	const xp_wchar_t* ptn, xp_size_t plen, int flags);

xp_size_t xp_wstrtodn (
	const xp_wchar_t* name, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_wstrxtodn (
	const xp_wchar_t* name, xp_size_t nsz, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_wstrfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_wchar_t* buf, xp_size_t bufsz);
xp_size_t xp_wstrxfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_wchar_t* buf, xp_size_t bufsz);

const xp_wchar_t* xp_wstrxword (
	const xp_wchar_t* str, xp_size_t len, const xp_wchar_t* word);
const xp_wchar_t* xp_wstrxcaseword (
	const xp_wchar_t* str, xp_size_t len, const xp_wchar_t* word);


/* string vector functions */
xp_wvstr_t* xp_wvstr_open (xp_wvstr_t* vec);
void xp_wvstr_close (xp_wvstr_t* vec);
void xp_wvstr_clear (xp_wvstr_t* vec);
int xp_wvstr_append (xp_wvstr_t* vec, const xp_wchar_t* str);

#ifdef __cplusplus
}
#endif

#endif
